Skip to content

stdlib: export opaque ets:continuation/0 - #11072

Merged
sverker merged 1 commit into
erlang:masterfrom
NelsonVides:stdlib/ets-export-opaque-continuation
Jun 24, 2026
Merged

stdlib: export opaque ets:continuation/0#11072
sverker merged 1 commit into
erlang:masterfrom
NelsonVides:stdlib/ets-export-opaque-continuation

Conversation

@NelsonVides

Copy link
Copy Markdown
Contributor

Expose ets:continuation/0 as an exported opaque type so callers can annotate state passed between select/match steps without resorting to term/0.

Publicly exported functions have ets:continuation/0 as their exported type so this type is kinda public already.

@github-actions

github-actions Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

CT Test Results

    2 files    100 suites   1h 1m 26s ⏱️
2 305 tests 2 254 ✅ 51 💤 0 ❌
2 725 runs  2 669 ✅ 56 💤 0 ❌

Results for commit 3021f38.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@IngelaAndin IngelaAndin added the team:VM Assigned to OTP team VM label May 4, 2026
sverker
sverker previously approved these changes May 4, 2026
@sverker sverker added this to the 30.0 milestone May 4, 2026
@sverker sverker added the stalled waiting for input by the Erlang/OTP team label May 4, 2026
@NelsonVides

Copy link
Copy Markdown
Contributor Author

@sverker 👋🏽 following up here 🙂

@sverker sverker added enhancement testing currently being tested, tag is used by OTP internal CI and removed stalled waiting for input by the Erlang/OTP team labels Jun 11, 2026
Comment thread lib/stdlib/src/ets.erl Outdated
Comment on lines +271 to +273
-opaque continuation() :: '$end_of_table'
| {table(),integer(),integer(),compiled_match_spec(),list(),integer()}
| {table(),_,_,integer(),compiled_match_spec(),list(),integer(),integer()}.

@sverker sverker Jun 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though type continuation() has been documented as "opaque" in text, there might be users that match on '$end_of_table', and I think dialyzer will start complaining about that if continuation() becomes opaque for real.

Another variant could be

-type continuation() :: '$end_of_table' | continuation_tuple().
-opaque continuation_tuple() :: {table(),...} | {table(),...}.

But I don't know if that would help, be the same, or even make it worse.

@jhogberg @lucioleKi @bjorng

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's a type A defined as a type union B | C, it's not a good idea to make B or C opaque (if they weren't previously). It would imply we can distinguish B and C despite at least one of them being opaque, which is a violation of opacity.
I wouldn't suggest making continuation_tuple() opaque. If continuation() is part of a type union for another type, I wouldn't suggest making it opaque either.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, should continuation/0 be exported just as a type? In that case it would leak the whole big tuple shapes, perhaps we want to make it

Suggested change
-opaque continuation() :: '$end_of_table'
| {table(),integer(),integer(),compiled_match_spec(),list(),integer()}
| {table(),_,_,integer(),compiled_match_spec(),list(),integer(),integer()}.
-type continuation() :: '$end_of_table' | tuple().

And entirely hide how it looks? The disadvantage would be that the module would lose internal type checking. What's the best option?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I want continuation() to be exported as not opaque. Even though the documentation text says it is "opaque", it can be returned as '$end_of_table' and I think I want the user to be able to match on '$end_of_table'. The alternative for the user is to do another ets:match/select call with Continuation as '$end_of_table' just to get back a '$end_of_table' that can be matched upon.

In other words, continuation() is in practice a semi-opaque type and I want it to keep being that. The type system does not support semi-opaqueness, so the next best thing is a non-opaque type with some explaining text.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to keep the two tuples as it is and mention in text not to match on them. A tuple() will just make the type checking worse, both internal and for the user.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a not to reflect that 👍🏽

Expose continuation/0 as an exported semi-opaque type so callers can annotate
state passed between select/match steps without using term().
@sverker
sverker force-pushed the stdlib/ets-export-opaque-continuation branch from 9487c5d to 3021f38 Compare June 23, 2026 17:50
@sverker
sverker merged commit 0c452ae into erlang:master Jun 24, 2026
31 checks passed
@NelsonVides
NelsonVides deleted the stdlib/ets-export-opaque-continuation branch August 21, 2026 06:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement team:VM Assigned to OTP team VM testing currently being tested, tag is used by OTP internal CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants